﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.GetBrowserTokenRequest
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IdentityModel.Policy;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Security;
using System.ServiceModel.Security.Tokens;
using System.Text;
using System.Xml;

namespace Microsoft.InfoCards
{
  internal class GetBrowserTokenRequest : GetTokenRequest
  {
    public const int POLICY_V1 = 1;
    public const int POLICY_V2 = 2;
    private GetBrowserTokenParameters m_params;
    private ServiceEndpoint m_svcEpr;
    private byte[] m_rawToken;
    private SelfIssuedAuthProofToken m_proofToken;
    private ProtocolProfile m_protocolProfile;

    public GetBrowserTokenRequest(
      Process callingProcess,
      WindowsIdentity callingIdentity,
      InfoCardUIAgent uiAgent,
      IntPtr rpcHandle,
      Stream inArgs,
      Stream outArgs)
      : base(callingProcess, callingIdentity, uiAgent, rpcHandle, inArgs, outArgs)
    {
      this.m_protocolProfile = new ProtocolProfile();
    }

    private static bool IsReferralToManagedIssuer(Binding issuerBinding)
    {
      bool flag = false;
      if (issuerBinding != null && issuerBinding.CreateBindingElements().Find<UseManagedPresentationBindingElement>() != null)
        flag = true;
      return flag;
    }

    protected override void OnMarshalInArgs()
    {
      BinaryReader reader = (BinaryReader) new InfoCardBinaryReader(this.InArgs, Encoding.Unicode);
      try
      {
        this.m_params = new GetBrowserTokenParameters();
        int paramVersion = reader.ReadInt32();
        if (1 != paramVersion && 2 != paramVersion)
          throw InfoCardTrace.ThrowHelperError((Exception) new InfoCardArgumentException(SR.GetString("InvalidFlagsSpecified")));
        this.m_params.Load(reader, paramVersion);
        if ((Uri) null == this.m_params.Issuer.PolicyUrl)
        {
          this.CreateInfoCardPolicyFromBrowserParams();
        }
        else
        {
          if (Utility.CompareUri(XmlNames.WSIdentity.SelfIssuerUriValue, this.m_params.Issuer.Address) || Utility.CompareUri(XmlNames.WSIdentity.AnonymousIssuerUriValue, this.m_params.Issuer.Address))
            throw InfoCardTrace.ThrowHelperError((Exception) new InfoCardArgumentException(SR.GetString("SelfOrAnonIssuerNotAllowedWhenMexSpecified", (object) this.m_params.Issuer.Address)));
          if ((Uri) null == this.m_params.Issuer.Address)
            throw InfoCardTrace.ThrowHelperError((Exception) new InfoCardArgumentException(SR.GetString("NoIssuerSpecifiedWhenMexIsSpecified")));
          ServiceEndpointCollection endpointCollection;
          try
          {
            endpointCollection = this.GetServiceEndpointCollection(this.m_params.Issuer.Address, this.m_params.Issuer.PolicyUrl);
          }
          catch (Exception ex)
          {
            if (InfoCardTrace.IsFatal(ex))
              throw;
            else
              endpointCollection = (ServiceEndpointCollection) null;
          }
          if (endpointCollection != null && endpointCollection.Find(this.m_params.Issuer.Address) != null)
          {
            ServiceEndpoint serviceEndpoint = endpointCollection.Find(this.m_params.Issuer.Address);
            if (!GetBrowserTokenRequest.IsReferralToManagedIssuer(serviceEndpoint.Binding) && this.DoesEndpointSatisfySecurityRequirements(serviceEndpoint) && this.DoesEndpointSatisfyIssuedTokenRequirements(serviceEndpoint))
            {
              if (Uri.UriSchemeHttps != this.m_params.Recipient.Address.Scheme)
                throw InfoCardTrace.ThrowHelperError((Exception) new InfoCardArgumentException(SR.GetString("RPStsWithNoSSLFailure")));
              this.m_svcEpr = serviceEndpoint;
              SecurityBindingElement securityBindingElement = serviceEndpoint.Binding.CreateBindingElements().Find<SecurityBindingElement>();
              InfoCardTrace.Assert(null != securityBindingElement, "No SecurityBindingElement was found in the BindingElementCollection");
              if (TrustVersion.WSTrust13 == securityBindingElement.MessageSecurityVersion.TrustVersion)
                this.m_protocolProfile.WSTrust = (XmlNames.IWSTrust) XmlNames.WSTrustOasis2007.Instance;
            }
          }
          this.CreateInfoCardPolicyFromBrowserParams();
        }
      }
      catch (InfoCardBaseException ex)
      {
        throw;
      }
      catch (Exception ex)
      {
        if (!InfoCardTrace.IsFatal(ex))
          throw InfoCardTrace.ThrowHelperError((Exception) new InfoCardArgumentException(SR.GetString("ServiceInvalidArguments"), ex));
        throw;
      }
    }

    private void CreateInfoCardPolicyFromBrowserParams()
    {
      CardSpacePolicyElement policyElement = this.m_params.CreatePolicyElement(this.m_protocolProfile);
      InfoCardPolicy browserTokenRequest = PolicyFactory.CreatePolicyForGetBrowserTokenRequest(policyElement, policyElement.PolicyNoticeLink, (uint) policyElement.PolicyNoticeVersion, RecipientIdentity.CreateIdentity(this.m_params.Recipient.CreateEndpointAddress(), true), PolicyUsageContext.Browser);
      browserTokenRequest.Validate();
      this.Policy = browserTokenRequest;
    }

    private bool DoesEndpointSatisfyIssuedTokenRequirements(ServiceEndpoint serviceEndpoint)
    {
      if (serviceEndpoint != null)
      {
        bool disallowedStpDetected = false;
        if (GetBrowserTokenRequest.TryGetNextStsIssuedTokenParameters(serviceEndpoint.Binding.CreateBindingElements(), ref disallowedStpDetected) != null)
          return true;
      }
      return false;
    }

    private bool DoesEndpointSatisfySecurityRequirements(ServiceEndpoint serviceEndpoint)
    {
      if (serviceEndpoint != null)
      {
        ISecurityCapabilities property = serviceEndpoint.Binding.GetProperty<ISecurityCapabilities>(new BindingParameterCollection());
        if (property != null && property.SupportedRequestProtectionLevel == ProtectionLevel.EncryptAndSign && (property.SupportedResponseProtectionLevel == ProtectionLevel.EncryptAndSign && property.SupportsClientAuthentication) && property.SupportsServerAuthentication)
          return true;
      }
      return false;
    }

    protected override void OnMarshalOutArgs()
    {
      BinaryWriter binaryWriter = new BinaryWriter(this.OutArgs, Encoding.Unicode);
      try
      {
        try
        {
          binaryWriter.Write(this.m_rawToken.Length);
          binaryWriter.Write(this.m_rawToken, 0, this.m_rawToken.Length);
        }
        finally
        {
          Array.Clear((Array) this.m_rawToken, 0, this.m_rawToken.Length);
        }
      }
      catch (Exception ex)
      {
        if (!InfoCardTrace.IsFatal(ex))
          throw InfoCardTrace.ThrowHelperError((Exception) new TrustExchangeException(SR.GetString("ServiceFailedToWriteToken"), ex));
        throw;
      }
    }

    protected override void OnProcess()
    {
      try
      {
        if (this.m_svcEpr == null)
        {
          base.OnProcess();
          if (this.ProcessingException != null)
            throw InfoCardTrace.ThrowHelperError(this.ProcessingException);
          using (MemoryStream memoryStream = new MemoryStream())
          {
            using (XmlWriter w = XmlWriter.Create((Stream) memoryStream, new XmlWriterSettings()
            {
              CloseOutput = false,
              Encoding = Encoding.UTF8,
              OmitXmlDeclaration = true
            }))
              this.Token.ProtectedToken.WriteTo(w);
            this.m_rawToken = new byte[memoryStream.Length - 3L];
            Array.Copy((Array) memoryStream.GetBuffer(), 3, (Array) this.m_rawToken, 0, Convert.ToInt32(memoryStream.Length - 3L));
          }
        }
        else
        {
          GetBrowserTokenRequest.CreateIssuedTokenClientCredentials clientCredentials = this.CreateClientCredentials(this.m_svcEpr);
          clientCredentials.Windows.AllowNtlm = false;
          Binding binding = GetBrowserTokenRequest.FedChainUpdateProxyAndRestrictTransportBindingWrapper(this.m_svcEpr.Binding, this.UserProxy);
          using (ChannelFactory<GetBrowserTokenRequest.ISts> channelFactory = new ChannelFactory<GetBrowserTokenRequest.ISts>(binding, this.m_svcEpr.Address))
          {
            channelFactory.Endpoint.Binding.OpenTimeout = new TimeSpan(5, 0, 0);
            channelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(5, 0, 0);
            channelFactory.Endpoint.Binding.ReceiveTimeout = new TimeSpan(5, 0, 0);
            channelFactory.Endpoint.Binding.CloseTimeout = new TimeSpan(5, 0, 0);
            channelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
            channelFactory.Endpoint.Behaviors.Add((IEndpointBehavior) clientCredentials);
            InfoCardTrace.Assert(!channelFactory.Credentials.Windows.AllowNtlm, "Should be false");
            GetBrowserTokenRequest.ISts sts = channelFactory.CreateChannel();
            if (this.Policy == null)
              this.CreateInfoCardPolicyFromBrowserParams();
            Message rstMsg = Message.CreateMessage(this.m_svcEpr.Binding.MessageVersion, this.m_protocolProfile.WSTrust.RequestSecurityTokenAction, (BodyWriter) new RequestSecurityTokenForGetBrowserToken(new RequestSecurityTokenParameters(this.m_svcEpr.Binding.MessageVersion.Addressing, this.m_params, this.m_protocolProfile, this.Policy, true)));
            Message rstrMsg = (Message) null;
            if (XmlNames.WSSpecificationVersion.WSTrustXmlSoap2005 == this.m_protocolProfile.WSTrust.Version)
              this.ExecuteCancelable((ClientRequest.AsyncEntryCallback) (() => rstrMsg = sts.ProcessRequestSecurityTokenFeb2005(rstMsg)), (ClientRequest.AsyncEntryCallback) (() => channelFactory.Abort()));
            else if (XmlNames.WSSpecificationVersion.WSTrustOasis2007 == this.m_protocolProfile.WSTrust.Version)
              this.ExecuteCancelable((ClientRequest.AsyncEntryCallback) (() => rstrMsg = sts.ProcessRequestSecurityTokenWSTrust13(rstMsg)), (ClientRequest.AsyncEntryCallback) (() => channelFactory.Abort()));
            else
              InfoCardTrace.Assert(false, "Unsupported version of WS-Trust detected");
            InfoCardTrace.Assert(null != rstrMsg, "Should have thrown before this if message is null");
            WSIdentityFaultException.ThrowIfFaultMessage(rstrMsg, CultureInfo.GetCultureInfo(this.UserLanguage));
            using (XmlReader readerAtBodyContents = (XmlReader) rstrMsg.GetReaderAtBodyContents())
            {
              using (MemoryStream memoryStream = new MemoryStream())
              {
                using (XmlWriter writer = XmlWriter.Create((Stream) memoryStream, new XmlWriterSettings()
                {
                  CloseOutput = false,
                  Encoding = Encoding.UTF8,
                  OmitXmlDeclaration = true
                }))
                  this.WriteRequestedTokenFrom(readerAtBodyContents, writer);
                this.m_rawToken = new byte[memoryStream.Length - 3L];
                Array.Copy((Array) memoryStream.GetBuffer(), 3, (Array) this.m_rawToken, 0, Convert.ToInt32(memoryStream.Length - 3L));
              }
            }
            channelFactory.Close();
          }
        }
      }
      catch (InfoCardBaseException ex)
      {
        throw;
      }
      catch (Exception ex)
      {
        if (!InfoCardTrace.IsFatal(ex))
          throw InfoCardTrace.ThrowHelperError((Exception) new TrustExchangeException(SR.GetString("ServiceSTSCommunicationFailed"), ex));
        throw;
      }
    }

    public static void WriteSourceUrlAppliesTo(
      XmlWriter writer,
      GetBrowserTokenParameters browserParams,
      ProtocolProfile profile)
    {
      EndpointAddress endpointAddress = browserParams.Recipient.CreateEndpointAddress();
      writer.WriteStartElement(profile.WSPolicy.DefaultPrefix, profile.WSPolicy.AppliesTo, profile.WSPolicy.Namespace);
      endpointAddress.WriteTo(AddressingVersion.WSAddressing10, writer);
      writer.WriteEndElement();
    }

    private static void CheckOptionalTokenParameters(
      SupportingTokenParameters oestp,
      IDictionary<string, SupportingTokenParameters> oostp,
      ref bool disallowedStpDetected)
    {
      ThrowOnMultipleAssignment<IssuedSecurityTokenParameters> issuedTokenParameters = new ThrowOnMultipleAssignment<IssuedSecurityTokenParameters>(SR.GetString("TooManyIssuedSecurityTokenParameters"));
      GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromSupportingTokenParameters(oestp, issuedTokenParameters, ref disallowedStpDetected);
      foreach (SupportingTokenParameters parameters in (IEnumerable<SupportingTokenParameters>) oostp.Values)
        GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromSupportingTokenParameters(parameters, issuedTokenParameters, ref disallowedStpDetected);
    }

    public static IssuedSecurityTokenParameters TryGetNextStsIssuedTokenParameters(
      BindingElementCollection bindingElements,
      ref bool disallowedStpDetected)
    {
      if (bindingElements == null)
        return (IssuedSecurityTokenParameters) null;
      ThrowOnMultipleAssignment<IssuedSecurityTokenParameters> issuedTokenParameters = new ThrowOnMultipleAssignment<IssuedSecurityTokenParameters>(SR.GetString("TooManyIssuedSecurityTokenParameters"));
      SecurityBindingElement securityBindingElement1 = bindingElements.Find<SecurityBindingElement>();
      if (securityBindingElement1 == null)
        return (IssuedSecurityTokenParameters) null;
      GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromSupportingTokenParameters(securityBindingElement1.EndpointSupportingTokenParameters, issuedTokenParameters, ref disallowedStpDetected);
      foreach (SupportingTokenParameters parameters in (IEnumerable<SupportingTokenParameters>) securityBindingElement1.OperationSupportingTokenParameters.Values)
        GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromSupportingTokenParameters(parameters, issuedTokenParameters, ref disallowedStpDetected);
      if (securityBindingElement1 is AsymmetricSecurityBindingElement)
      {
        AsymmetricSecurityBindingElement securityBindingElement2 = (AsymmetricSecurityBindingElement) securityBindingElement1;
        GetBrowserTokenRequest.CheckAndAssignIssuedTokenParameters(securityBindingElement2.InitiatorTokenParameters, issuedTokenParameters, ref disallowedStpDetected);
        GetBrowserTokenRequest.CheckAndAssignIssuedTokenParameters(securityBindingElement2.RecipientTokenParameters, issuedTokenParameters, ref disallowedStpDetected);
      }
      else if (securityBindingElement1 is SymmetricSecurityBindingElement)
      {
        SecurityTokenParameters protectionTokenParameters = ((SymmetricSecurityBindingElement) securityBindingElement1).ProtectionTokenParameters;
        if (protectionTokenParameters is SecureConversationSecurityTokenParameters)
        {
          SecureConversationSecurityTokenParameters securityTokenParameters = (SecureConversationSecurityTokenParameters) protectionTokenParameters;
          BindingElementCollection bindingElements1 = new BindingElementCollection();
          if (securityTokenParameters.BootstrapSecurityBindingElement != null)
            bindingElements1.Add((BindingElement) securityTokenParameters.BootstrapSecurityBindingElement);
          GetBrowserTokenRequest.CheckAndAssignIssuedTokenParameters((SecurityTokenParameters) GetBrowserTokenRequest.TryGetNextStsIssuedTokenParameters(bindingElements1, ref disallowedStpDetected), issuedTokenParameters, ref disallowedStpDetected);
        }
        else
          GetBrowserTokenRequest.CheckAndAssignIssuedTokenParameters(protectionTokenParameters, issuedTokenParameters, ref disallowedStpDetected);
      }
      GetBrowserTokenRequest.CheckOptionalTokenParameters(securityBindingElement1.OptionalEndpointSupportingTokenParameters, securityBindingElement1.OptionalOperationSupportingTokenParameters, ref disallowedStpDetected);
      return issuedTokenParameters.Value;
    }

    public static void CheckAndAssignIssuedTokenParameters(
      SecurityTokenParameters stp,
      ThrowOnMultipleAssignment<IssuedSecurityTokenParameters> issuedTokenParameters,
      ref bool disallowedStpDetected)
    {
      if (stp == null)
        return;
      InfoCardTrace.Assert(null == stp as SecureConversationSecurityTokenParameters, "Should have already filtered this");
      if (stp is IssuedSecurityTokenParameters || stp is RsaSecurityTokenParameters || (stp is SslSecurityTokenParameters || stp is X509SecurityTokenParameters))
        issuedTokenParameters.Value = stp as IssuedSecurityTokenParameters;
      else
        disallowedStpDetected = true;
    }

    private static void GetIssuedSecurityTokenParametersFromSupportingTokenParameters(
      SupportingTokenParameters parameters,
      ThrowOnMultipleAssignment<IssuedSecurityTokenParameters> issuedTokenParameters,
      ref bool disallowedStpDetected)
    {
      GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromCollection(parameters.Endorsing, issuedTokenParameters, ref disallowedStpDetected);
      GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromCollection(parameters.SignedEndorsing, issuedTokenParameters, ref disallowedStpDetected);
      GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromCollection(parameters.Signed, issuedTokenParameters, ref disallowedStpDetected);
      GetBrowserTokenRequest.GetIssuedSecurityTokenParametersFromCollection(parameters.SignedEncrypted, issuedTokenParameters, ref disallowedStpDetected);
    }

    private static void GetIssuedSecurityTokenParametersFromCollection(
      Collection<SecurityTokenParameters> collection,
      ThrowOnMultipleAssignment<IssuedSecurityTokenParameters> issuedTokenParameters,
      ref bool disallowedStpDetected)
    {
      foreach (SecurityTokenParameters stp in collection)
      {
        if (stp is SecureConversationSecurityTokenParameters)
        {
          SecureConversationSecurityTokenParameters securityTokenParameters = (SecureConversationSecurityTokenParameters) stp;
          BindingElementCollection bindingElements = new BindingElementCollection();
          if (securityTokenParameters.BootstrapSecurityBindingElement != null)
            bindingElements.Add((BindingElement) securityTokenParameters.BootstrapSecurityBindingElement);
          GetBrowserTokenRequest.CheckAndAssignIssuedTokenParameters((SecurityTokenParameters) GetBrowserTokenRequest.TryGetNextStsIssuedTokenParameters(bindingElements, ref disallowedStpDetected), issuedTokenParameters, ref disallowedStpDetected);
        }
        else
          GetBrowserTokenRequest.CheckAndAssignIssuedTokenParameters(stp, issuedTokenParameters, ref disallowedStpDetected);
      }
    }

    private GetBrowserTokenRequest.CreateIssuedTokenClientCredentials CreateClientCredentials(
      ServiceEndpoint svcEpr)
    {
      GetBrowserTokenRequest.CreateIssuedTokenClientCredentials clientCredentials = new GetBrowserTokenRequest.CreateIssuedTokenClientCredentials(this);
      EndpointAddress endpointAddress = svcEpr.Address;
      Binding binding = svcEpr.Binding;
      X509Certificate2Collection certificate2Collection = new X509Certificate2Collection();
      bool disallowedStpDetected = false;
      try
      {
        while (binding != null)
        {
          IssuedSecurityTokenParameters issuedTokenParameters = GetBrowserTokenRequest.TryGetNextStsIssuedTokenParameters(binding.CreateBindingElements(), ref disallowedStpDetected);
          if (issuedTokenParameters != null)
          {
            if (disallowedStpDetected)
              throw InfoCardTrace.ThrowHelperError((Exception) new UnsupportedPolicyOptionsException());
            if (!((EndpointAddress) null == issuedTokenParameters.IssuerAddress) && !((Uri) null == issuedTokenParameters.IssuerAddress.Uri))
            {
              X509CertificateEndpointIdentity identity = endpointAddress.Identity as X509CertificateEndpointIdentity;
              if (identity != null)
              {
                certificate2Collection.AddRange(identity.Certificates);
                certificate2Collection.Remove(identity.Certificates[0]);
                bool chainTrustPassed = false;
                InfoCardX509Validator.ValidateChainOrPeer(identity.Certificates[0], certificate2Collection, out chainTrustPassed);
                clientCredentials.ServiceCertificate.ScopedCertificates.Add(endpointAddress.Uri, identity.Certificates[0]);
              }
              binding = issuedTokenParameters.IssuerBinding;
              endpointAddress = issuedTokenParameters.IssuerAddress;
            }
            else
              break;
          }
          else
            break;
        }
        if (this.m_params.Issuer.LeafCertificate != null)
        {
          bool chainTrustPassed = false;
          InfoCardX509Validator.ValidateChainOrPeer(this.m_params.Issuer.LeafCertificate, this.m_params.Issuer.SupportingCertificates, out chainTrustPassed);
          clientCredentials.ServiceCertificate.DefaultCertificate = this.m_params.Issuer.LeafCertificate;
          certificate2Collection.AddRange(this.m_params.Issuer.SupportingCertificates);
        }
        else
        {
          X509CertificateEndpointIdentity identity = svcEpr.Address.Identity as X509CertificateEndpointIdentity;
          if (identity == null)
            throw InfoCardTrace.ThrowHelperError((Exception) new TrustExchangeException(SR.GetString("InvalidIPSTSPolicy")));
          clientCredentials.ServiceCertificate.DefaultCertificate = identity.Certificates[0];
          certificate2Collection.AddRange(identity.Certificates);
          certificate2Collection.Remove(identity.Certificates[0]);
        }
        InfoCardTrace.Assert(null != clientCredentials.ServiceCertificate.DefaultCertificate, "This is configured in both cases above - either via the incoming params or via the endpoint retrieved from mex");
        clientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
        clientCredentials.ServiceCertificate.Authentication.CustomCertificateValidator = InfoCardX509Validator.Create(certificate2Collection);
      }
      catch (SecurityTokenValidationException ex)
      {
        throw InfoCardTrace.ThrowHelperError((Exception) new IdentityValidationException(SR.GetString("RecipientCertificateNotValid"), (Exception) ex));
      }
      return clientCredentials;
    }

    private void WriteRequestedTokenFrom(XmlReader reader, XmlWriter writer)
    {
      while (reader.Read())
      {
        if (reader.IsStartElement(this.m_protocolProfile.WSTrust.RequestedSecurityToken, this.m_protocolProfile.WSTrust.Namespace))
        {
          reader.Read();
          writer.WriteNode(reader, false);
          return;
        }
      }
      throw InfoCardTrace.ThrowHelperError((Exception) new TrustExchangeException(SR.GetString("NoTokenReturned")));
    }

    private ServiceEndpointCollection GetServiceEndpointCollection(
      Uri serviceUri,
      Uri mexUri)
    {
      bool flag = false;
      InfoCardMetadataExchangeClient mex = new InfoCardMetadataExchangeClient();
      mex.Proxy = this.UserProxy;
      MetadataSet metadataSet = (MetadataSet) null;
      mex.ResolveMetadataReferences = true;
      mex.MaximumResolvedReferences = InfoCardConstants.MaximumMexChainLength;
      EndpointAddress metadataAddress = new EndpointAddress(mexUri, new AddressHeader[0]);
      try
      {
        this.ExecuteCancelable((ClientRequest.AsyncEntryCallback) (() => metadataSet = mex.GetMetadata(metadataAddress)), (ClientRequest.AsyncEntryCallback) (() => mex.Abort()));
        flag = true;
      }
      catch (Exception ex)
      {
        if (InfoCardTrace.IsFatal(ex))
          throw;
      }
      if (!flag)
      {
        try
        {
          this.ExecuteCancelable((ClientRequest.AsyncEntryCallback) (() => metadataSet = mex.GetMetadata(mexUri, MetadataExchangeClientMode.HttpGet)), (ClientRequest.AsyncEntryCallback) (() => mex.Abort()));
          flag = true;
        }
        catch (Exception ex)
        {
          if (InfoCardTrace.IsFatal(ex))
            throw;
        }
      }
      if (!flag)
        throw InfoCardTrace.ThrowHelperError((Exception) new TrustExchangeException(SR.GetString("EndpointNotFound")));
      WsdlImporter imp = new WsdlImporter(metadataSet);
      imp.State.Add((object) "MetadataExchangeClientKey", (object) mex);
      ServiceEndpointCollection serviceEndpoints = (ServiceEndpointCollection) null;
      this.ExecuteCancelable((ClientRequest.AsyncEntryCallback) (() => serviceEndpoints = imp.ImportAllEndpoints()), (ClientRequest.AsyncEntryCallback) null);
      return serviceEndpoints;
    }

    private static BindingElementCollection FedChainUpdateProxyForHttpAndRestrictTransportBinding(
      BindingElementCollection bindingElements,
      IWebProxy proxy)
    {
      bindingElements = Utility.UpdateProxyForHttpAndRestrictTransportBinding(bindingElements, proxy, true);
      bool disallowedStpDetected = false;
      IssuedSecurityTokenParameters issuedTokenParameters = GetBrowserTokenRequest.TryGetNextStsIssuedTokenParameters(bindingElements, ref disallowedStpDetected);
      if (issuedTokenParameters != null && (EndpointAddress) null != issuedTokenParameters.IssuerAddress && ((Uri) null != issuedTokenParameters.IssuerAddress.Uri && issuedTokenParameters.IssuerBinding != null))
        issuedTokenParameters.IssuerBinding = (Binding) new CustomBinding(GetBrowserTokenRequest.FedChainUpdateProxyForHttpAndRestrictTransportBinding(issuedTokenParameters.IssuerBinding.CreateBindingElements(), proxy));
      return bindingElements;
    }

    private static Binding FedChainUpdateProxyAndRestrictTransportBindingWrapper(
      Binding binding,
      IWebProxy proxy)
    {
      return (Binding) new CustomBinding(GetBrowserTokenRequest.FedChainUpdateProxyForHttpAndRestrictTransportBinding(binding.CreateBindingElements(), proxy));
    }

    private SecurityToken CreateIssuedToken(
      CardSpacePolicyElement[] policyElements,
      SecurityTokenSerializer tokenSerializer)
    {
      WindowsImpersonationContext impersonationContext = this.RequestorIdentity.Impersonate();
      try
      {
        try
        {
          int index1 = policyElements.Length - 1;
          InfoCardTrace.Assert(0 <= index1, "lastElementIndex should be non-negative");
          if (policyElements[index1].IsManagedIssuer)
            --index1;
          int length = index1;
          if (0 < length)
          {
            InfoCardPolicy[] infoCardPolicyArray = new InfoCardPolicy[length];
            for (int index2 = 0; index2 < length; ++index2)
            {
              infoCardPolicyArray[index2] = PolicyFactory.CreatePolicyForIntermediateGetBrowserTokenRequest(policyElements[index2], (Uri) null, 0U, (RecipientIdentity) null);
              infoCardPolicyArray[index2].Validate();
            }
          }
          InfoCardPolicy browserTokenRequest = PolicyFactory.CreatePolicyForGetBrowserTokenRequest(policyElements[index1], this.m_params.PrivacyUrl, this.m_params.PrivacyVersion, RecipientIdentity.CreateIdentity(this.m_params.Recipient.CreateEndpointAddress(), true), PolicyUsageContext.GetToken);
          browserTokenRequest.Validate();
          this.Policy = browserTokenRequest;
          base.OnProcess();
          if (this.ProcessingException != null)
            throw InfoCardTrace.ThrowHelperError(this.ProcessingException);
          SecurityKeyIdentifierClause internalTokenReference = tokenSerializer.ReadKeyIdentifierClause((XmlReader) Utility.CreateReaderWithQuotas(this.Token.InternalTokenReference));
          SecurityKeyIdentifierClause externalTokenReference = tokenSerializer.ReadKeyIdentifierClause((XmlReader) Utility.CreateReaderWithQuotas(this.Token.ExternalTokenReference));
          this.m_proofToken = this.Token.SymmetricProof != null ? new SelfIssuedAuthProofToken(new InMemorySymmetricSecurityKey(this.Token.SymmetricProof.Key), this.Token.ExpirationTime) : new SelfIssuedAuthProofToken(this.GetPrivateCryptography(), this.Token.ExpirationTime);
          return (SecurityToken) new GenericXmlSecurityToken(this.Token.ProtectedToken, (SecurityToken) this.m_proofToken, this.Token.EffectiveTime, this.Token.ExpirationTime, internalTokenReference, externalTokenReference, (ReadOnlyCollection<IAuthorizationPolicy>) null);
        }
        finally
        {
          impersonationContext.Undo();
        }
      }
      catch
      {
        throw;
      }
    }

    protected override void OnDisposeAsUser()
    {
      base.OnDisposeAsUser();
      if (this.m_proofToken == null)
        return;
      this.m_proofToken.Dispose();
      this.m_proofToken = (SelfIssuedAuthProofToken) null;
    }

    private class CreateIssuedTokenClientCredentials : ClientCredentials
    {
      private GetBrowserTokenRequest request;

      public CreateIssuedTokenClientCredentials(GetBrowserTokenRequest request)
      {
        InfoCardTrace.ThrowInvalidArgumentConditional(request == null, nameof (request));
        this.request = request;
      }

      protected internal CreateIssuedTokenClientCredentials(
        GetBrowserTokenRequest.CreateIssuedTokenClientCredentials other)
        : base((ClientCredentials) other)
      {
        this.request = other.request;
      }

      protected override ClientCredentials CloneCore()
      {
        return (ClientCredentials) new GetBrowserTokenRequest.CreateIssuedTokenClientCredentials(this);
      }

      protected internal override SecurityToken GetInfoCardSecurityToken(
        bool requiresInfoCard,
        CardSpacePolicyElement[] chain,
        SecurityTokenSerializer tokenSerializer)
      {
        return this.request.CreateIssuedToken(chain, tokenSerializer);
      }

      public override void ApplyClientBehavior(
        ServiceEndpoint serviceEndpoint,
        ClientRuntime behavior)
      {
        base.ApplyClientBehavior(serviceEndpoint, behavior);
        bool flag = false;
        foreach (IInteractiveChannelInitializer channelInitializer in behavior.InteractiveChannelInitializers)
        {
          if (channelInitializer is InfocardInteractiveChannelInitializer)
          {
            flag = true;
            break;
          }
        }
        if (!flag)
          throw InfoCardTrace.ThrowHelperError((Exception) new TrustExchangeException(SR.GetString("IdentityProviderRequestedUnsupportedAuthType")));
      }
    }

    [ServiceContract]
    internal interface ISts
    {
      [OperationContract(Action = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", Name = "ProcessRequestSecurityTokenFeb2005", ProtectionLevel = ProtectionLevel.EncryptAndSign, ReplyAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue")]
      Message ProcessRequestSecurityTokenFeb2005(Message rstMessage);

      [OperationContract(Action = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue", Name = "ProcessRequestSecurityTokenWSTrust13", ProtectionLevel = ProtectionLevel.EncryptAndSign, ReplyAction = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal")]
      Message ProcessRequestSecurityTokenWSTrust13(Message rstMessage);
    }
  }
}
